/*
 * alignStrings.cpp
 *
 *  Created on: 2011-09-16
 *      Author: pawel
 */
#include"alignStrings.h"
#include"../smart2DArray.h"
#include"../enumTypes.h"
#include<string.h>
#include<stdexcept>

#define ALIGN_IDENTITY '|'
#define ALIGN_SIMILARITY ':'
#define ALIGN_GAP '-'
#define ALIGN_MISMATCH '.'
#define ALIGN_EMPTY ' '

btrack::alignStrings::alignStrings(const size_t length)throw(std::logic_error)
:sQStr(1,length),sDbStr(1,length),sAlign(1,length),length(length),position(length-2),off(1),
stopSet(false),queryAlignStart(0),queryAlignStop(0),dbAlignStart(0),dbAlignStop(0),
identity(0),similarity(0),gaps(0)
{
	if(length<2)throw std::logic_error("Length is too small");
qStr = (sQStr.getPtr())[0];
dbStr = (sDbStr.getPtr())[0];
aStr = (sAlign.getPtr())[0];
memset(qStr,0,length*sizeof(char));
memset(dbStr,0,length*sizeof(char));
memset(aStr,0,length*sizeof(char));
}
btrack::alignStrings::alignStrings(const btrack::alignStrings& obj)
:sQStr(1,obj.length),sDbStr(1,obj.length),sAlign(1,obj.length),length(obj.length),position(obj.position),off(obj.off),
stopSet(obj.stopSet),queryAlignStart(obj.queryAlignStart),queryAlignStop(obj.queryAlignStop),
dbAlignStart(obj.dbAlignStart),dbAlignStop(obj.dbAlignStop),identity(obj.identity),similarity(obj.similarity),
gaps(obj.gaps)
{
	qStr = (sQStr.getPtr())[0];
	dbStr = (sDbStr.getPtr())[0];
	aStr = (sAlign.getPtr())[0];
	memset(qStr,0,length*sizeof(char));
	memset(dbStr,0,length*sizeof(char));
	memset(aStr,0,length*sizeof(char));

	size_t cLen = length - position ;
	memcpy((void*)(qStr+position),(void*)(obj.qStr + position),cLen);
	memcpy((void*)(dbStr+position),(void*)(obj.dbStr + position),cLen);
	memcpy((void*)(aStr+position),(void*)(obj.aStr + position),cLen);
}
int btrack::alignStrings::insert(const char& quer,const char& db,const char& direction){
	if(direction & DR_DIAG){
		if(direction & DR_MATCH){
			qStr[position] = quer;
			dbStr[position] = db;
			aStr[position] = ALIGN_SIMILARITY;
			similarity++;
		}
		else if(direction & DR_MISMATCH){
			qStr[position] = quer;
			dbStr[position] = db;
			aStr[position] = ALIGN_MISMATCH;
		}
		else if(direction & DR_IDENTITY){
			qStr[position] = quer;
			dbStr[position] = db;
			aStr[position] = ALIGN_IDENTITY;
			similarity++;
			identity++;

		}

	}
	else if(direction & DR_UP){
		qStr[position]	= quer;
		dbStr[position]	= ALIGN_GAP;
		aStr[position]	= ALIGN_EMPTY;
		gaps++;
	}
	else if(direction & DR_LEFT){
		qStr[position]	= ALIGN_GAP;
		dbStr[position]	= db;
		aStr[position]	= ALIGN_EMPTY;
		gaps++;
	}
	if(position == 0){
		off =0;
	}
	if(position>0){
		position--;
	}
	return 0;
}
int btrack::alignStrings::isStopSet()const{return stopSet;}
int btrack::alignStrings::setStop(const size_t &row,const size_t &col){
	if(!stopSet){
	stopSet = true;
	queryAlignStop = row;
	dbAlignStop = col;
	return 0;
	}
	return 1;
}
int btrack::alignStrings::setStart(const size_t &row,const size_t &col){
	queryAlignStart	=	row;
	dbAlignStart	=	col;
	return 0;
}
double btrack::alignStrings::getIdentity()const{return (double)identity/(double)(length - position -1);}
double btrack::alignStrings::getSimilarity()const{return (double)similarity/(double)(length - position -1);}
double btrack::alignStrings::getGaps()const{return (double)gaps/(double)(length - position -1);}

char* btrack::alignStrings::getTrimmedAStr(){
	return (char*)(aStr + position + off);
}

char* btrack::alignStrings::getTrimmedQStr(){
	return (char*)(qStr + position + off);
}
char* btrack::alignStrings::getTrimmedDbStr(){
	return (char*)(dbStr + position + off);
}
size_t btrack::alignStrings::getQueryAlignStart()const{
	return queryAlignStart;
}
size_t btrack::alignStrings::getQueryAlignStop()const{
	return queryAlignStop;
}
size_t btrack::alignStrings::getDbAlignStart()const{
	return dbAlignStart;
}
size_t btrack::alignStrings::getDbAlignStop()const{
	return dbAlignStop;
}
